package com.jar.exercise.反射;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.Properties;

/**
 * @author ZhangShengHao
 * @className ReflectionTest
 * @description TODO
 * @date 2020/1/24 17:41
 */
public class ReflectionTest {
	public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
		Class<Student> studentClass = Student.class;
		/**
		 * 通过反射创建对象
		 */
		Constructor<Student> constructor = studentClass.getConstructor(String.class, Integer.class);
		Student student = constructor.newInstance("张胜豪", 123);
		System.out.println(student);
		/**
		 * 通过反射调用方法
		 */
		Field name = studentClass.getDeclaredField("name");
		//开启访问权限，因为属性被私有化
		name.setAccessible(true);
		name.set(student, "张小豪");
		System.out.println(student);
		/**
		 * 通过反射调用方法
		 */
		Method show = studentClass.getDeclaredMethod("show");
		show.setAccessible(true);
		show.invoke(student);

		System.out.println(1 & 3);
	}

	/**
	 * 获取运行时类带泛型的类的泛型
	 */
	@Test
	public void test1() {
		Class<Student> studentClass = Student.class;
		Type genericSuperclass = studentClass.getGenericSuperclass();
		Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments();
		System.out.println(actualTypeArguments[0].getTypeName());

	}

	/**
	 * 通过反射调用show（）方法
	 */
	@Test
	public void test2() throws Exception {
		Class<Student> studentClass = Student.class;
		Student s = studentClass.newInstance();
		Method show = studentClass.getDeclaredMethod("show");
		show.setAccessible(true);
		show.invoke(s);
	}

	/**
	 * 读取配置文件使用类加载器
	 */
	@Test
	public void test3() throws Exception {
		ClassLoader classLoader = ReflectionTest.class.getClassLoader();
		InputStream resourceAsStream = classLoader.getResourceAsStream("反射/jdbc.properties");
		Properties properties = new Properties();
		properties.load(resourceAsStream);
		String name = properties.getProperty("name");
		String sex = properties.getProperty("sex");
		System.out.println(name);
		System.out.println(sex);

	}

	/**
	 * 使用io读取
	 */
	@Test
	public void test4() throws Exception {
		InputStream stream = new FileInputStream("D:\\Study\\IDEA\\JavaProject\\great-project-spring-boot\\exercise\\src\\main\\java\\com\\jar\\exercise\\反射\\jdbc.properties");
		Properties properties = new Properties();
		properties.load(stream);
		String name = properties.getProperty("name");
		String sex = properties.getProperty("sex");
		System.out.println(name);
		System.out.println(sex);

	}
	@Test
	public void test5(){
		try {
			Class<?> stuClass = Class.forName("com.jar.exercise.反射.Student");
			System.out.println(stuClass.getName());
			System.out.println(Arrays.toString(stuClass.getConstructors()));
//			Student student = (Student) stuClass.newInstance();
//			System.out.println(student);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Test
	public void test6(){
		Student student = new Student();
		Class<? extends Student> aClass = student.getClass();
		System.out.println(aClass);
	}

}
